package cn.org.spring.wechar.controller;

import cn.org.spring.common.util.HttpClientUtils;
import cn.org.spring.common.util.StringUtil;
import cn.org.spring.common.util.XmlUtils;
import cn.org.spring.wechar.config.WeCharConfig;
import cn.org.spring.wechar.constant.MessageType;
import cn.org.spring.wechar.constant.WeCharConstant;
import cn.org.spring.wechar.context.ContextMessageFactory;
import cn.org.spring.wechar.utils.AccessAuthentication;
import com.alibaba.fastjson.JSON;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @auther: wanghongjie
 * @blame: wanghongjie
 * @date: 2020-10-08 17:24
 * @Description:
 */
@RestController
@RequestMapping("/v1/weChar")
public class WeCharController {


    @Autowired
    private WeCharConfig weCharConfig;

    private String token = "fxz";


    /**
     * 1: 获取第三方平台component_access_token
     * 根据第三方的平台的参数 获取第三方平台接口的调用凭据 用于后面获取预授权码
     */
    @SneakyThrows
    @GetMapping("/getComponentAccessToken")
    public void getComponentAccessToken() {
        Map<String, String> map = new HashMap<>();
        map.put("component_appid", weCharConfig.getComponentAppid());
        map.put("component_appsecret", weCharConfig.getComponentAppsecret());
        map.put("component_verify_ticket", weCharConfig.getComponentVerifyTicket());
        String result = HttpClientUtils.post(WeCharConstant.COMPONENT_ACCESS_TOKEN, map);
        String componentAccessToken = JSON.parseObject(result).getString("component_access_token");
        String expiresIn = JSON.parseObject(result).getString("expires_in");
        if (StringUtil.isBlank(componentAccessToken)) {
            throw new RuntimeException("componentAccessToken为空!");
        }

        //TODO 存到redis
        weCharConfig.setComponentAccessToken(componentAccessToken);

        //获取预授权码
        getPreAuthCode(componentAccessToken);
    }

    /**
     * 2:  获取预授权码
     * 根据第三方平台component_access_token获取到预授权码  用于后面的PC授权
     */
    @SneakyThrows
    public void getPreAuthCode(String componentAccessToken) {
        Map<String, String> map = new HashMap<>();
        map.put("component_appid", weCharConfig.getComponentAppid());
        String result = HttpClientUtils.post(WeCharConstant.PRE_AUTH_CODE.replace("COMPONENT_ACCESS_TOKEN", componentAccessToken), map);
        String preAuthCode = JSON.parseObject(result).getString("pre_auth_code ");
        String expiresIn = JSON.parseObject(result).getString("expires_in");
        if (StringUtil.isBlank(componentAccessToken)) {
            throw new RuntimeException("preAuthCode为空!");
        }

        //TODO 存到redis
        weCharConfig.setPreAuthCode(preAuthCode);

        //已经获取预授权码  前端通过携带参数第三方平台方appid、预授权码、回调URI、授权的帐号类型访问 PC_AUTH_LINK 生成二维码  （前端完成）
        //用户通过扫描二维码 进行授权 授权成功后页面跳转到回调url 其中回调url携带着授权码authorization_code  (得到授权码)
        //通过回调url中的授权码authorization_code 我们访问AUTHORIZER_REFRESH_TOKEN得到authorizer_refresh_token和authorizer_access_token
        //authorizer_access_token过期时 通过刷新token 访问AUTHORIZER_ACCESS_TOKEN 得到得到authorizer_access_token
    }

    /**
     * 前端已经获取到了授权码 我们通过授权码访问接口 可以获取刷新token和token
     */
    @SneakyThrows
    @GetMapping("/getAuthorizerInfo/{authorizationCode}")
    public void getAuthorizerInfo(@PathVariable String authorizationCode) {
        Map<String, String> map = new HashMap<>();
        map.put("component_appid", weCharConfig.getComponentAppid());
        map.put("authorization_code", authorizationCode);
        String result = HttpClientUtils.post(WeCharConstant.AUTHORIZER_REFRESH_TOKEN.replace("COMPONENT_ACCESS_TOKEN", weCharConfig.getComponentAccessToken()), map);
        String authorizerAppid = JSON.parseObject(result).getString("authorizer_appid ");
        String authorizerAccessToken = JSON.parseObject(result).getString("authorizer_access_token");
        String expiresIn = JSON.parseObject(result).getString("expires_in");
        String authorizerRefreshToken = JSON.parseObject(result).getString("authorizer_refresh_token");

        //TODO 存到redis

    }

    /**
     * authorizerAccessToken过期时 可以携带刷新token通过此接口重新获取
     */
    @SneakyThrows
    @GetMapping("/refreshToken")
    public void refreshToken() {
        Map<String, String> map = new HashMap<>();
        map.put("component_appid", weCharConfig.getComponentAppid());
        map.put("authorizer_appid", weCharConfig.getAuthorizerAppid());
        map.put("authorizer_refresh_token", weCharConfig.getAuthorizerRefreshToken());
        String result = HttpClientUtils.post(WeCharConstant.AUTHORIZER_ACCESS_TOKEN.replace("COMPONENT_ACCESS_TOKEN", weCharConfig.getComponentAccessToken()), map);
        String authorizerAccessToken = JSON.parseObject(result).getString("authorizer_access_token ");
        String expiresIn = JSON.parseObject(result).getString("expires_in");
        String authorizerRefreshToken = JSON.parseObject(result).getString("authorizer_refresh_token");
    }

    /**
     * authorizer_access_token过期时 通过刷新token 访问接口 得到authorizer_access_token
     */
    public void refreshAccessToken() {

    }

    /*------------------------------------------------------------------------------------------------------------------------------------------------*/
    @Autowired
    private ContextMessageFactory contextMessageFactory;

    @GetMapping
    public String getWeChar(@RequestParam String signature,
                            @RequestParam String timestamp,
                            @RequestParam String nonce,
                            @RequestParam String echostr) {
        System.out.println("signature :" + signature);
        System.out.println("timestamp :" + timestamp);
        System.out.println("nonce :" + nonce);
        System.out.println("echostr :" + echostr);
        if (AccessAuthentication.of(token, timestamp, nonce, signature).checkSignature()) {
            return echostr;
        }
        return echostr;
    }

    @PostMapping
    public String post(@RequestBody String message) throws Exception {
        System.out.println("接收到微信公众平台消息：" + message);
        Map<String, Object> stringObjectMap = XmlUtils.xmlStrToMap(message);
        MessageType msgType = MessageType.getType(stringObjectMap.get("MsgType").toString());
        return contextMessageFactory.doAction(msgType, stringObjectMap);
    }


    /**
     * 服务检查接口
     *
     * @return
     */
    @GetMapping("/isWorker")
    public String isWorker() {
        return "Is Worker !";
    }
    /*-----------------------------------------------------------------------------------------------------------------------------------------*/
}
